<?php

namespace Org\SueCrypt;

/**
 * SuEncrypt 实用加密类
 * 用途：数组转序列号,字符串加密,支持中文
 * 吐槽：PHP加密功能的完成总算解决了自己的一个心病。
 *  以前somda挺强大的，但是逻辑想法太复杂，原来的草稿又遗失了，现在想看代码回忆流程有点头疼。
 *  这个加密版本比较简洁，性能也还不错，速度方面理论上应该比somda要高，虽然强度没有somda复杂，
 *  但是满足生产环境的需求应该是绰绰有余了，关键是要把本文件加密，不然被下载了就容易破解了。
 * @since 1.0 <2015-7-9> SoChishun Added.
 */
class SueNumix {
    
    // ==数字加密==
    private static $dict = array(
        '123456789',
        '0872953164',
        '5346829017',
        '8420157396',
        '9652473180',
        '1408792536',
        '8270315964',
        '6910578423',
        '8415920673',
        '0275819463',
        '5863724019',
    );

    /**
     * 混淆数值
     * <br />支持浮点、负数等
     * @param number $num 浮点数、负数等各种数值
     * @return string 返回无符号整数值,比原长度多2位,最少4位
     * @since 1.0 <2015-7-9> SoChishun Added.
     * @example number_mix(-1699123.0123) => 50416041339121
     */
    public static function encrypt($num) {
        if (!is_numeric($num)) {
            return $num;
        }
        $str = strval($num);
        $prefix = '0';
        switch ($str[0]) {
            case '+':
                $str = substr($str, 1);
                break;
            case '-':
                $prefix = '1';
                $str = substr($str, 1);
                break;
        }
        if (false !== ($idot = strrpos($str, '.'))) {
            $prefix.=$idot;
            $str = str_replace('.', '', $str);
        } else {
            $prefix.='0';
        }
        $str = $prefix . $str; // [id][symo_flag][float_flag]
        $id = rand(1, 9);
        $dict_org = '1234567890';
        $dictmix = self::$dict[$id];
        $n = strlen($str) - 1;
        $out = '';
        while ($n >= 0) {
            $i = strpos($dict_org, $str[$n]);
            $out.=$dictmix[$i];
            $n--;
        }
        return $id . $out;
    }

    /**
     * 数值反混淆
     * @param number $num 整数值
     * @return string
     * @since 1.0 <2015-7-9> SoChishun Added.
     * @example number_demix(50416041339121) => -1699123.0123
     */
    public static function decrypt($num) {
        if (!$num || !ctype_digit($num)) {
            return $num;
        }
        $str = strval($num);
        $id = $str[0];
        $dict_org = '1234567890';
        $dictmix = self::$dict[$id];
        $str = substr($str, 1);
        $n = strlen($str) - 1;
        $out = '';
        while ($n >= 0) {
            $i = strpos($dictmix, $str[$n]);
            $out.=$dict_org[$i];
            $n--;
        }
        $symbol = $out[0];
        $idot = $out[1];
        $str = substr($out, 2);
        if ('0' != $idot) {
            $str = substr_replace($str, '.', $idot, 0);
        }
        if ('1' == $symbol) {
            $str = '-' . $str;
        }
        return $str;
    }

    // ==/数字加密==
}
